{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Training an image classifier\n",
    "\n",
    "我们会遵照一下几个步骤：\n",
    "\n",
    "- 使用torchvision加载标准化的CIFAR10 训练集和测试集\n",
    "- 定义卷积神经网络\n",
    "- 定义Loss\n",
    "- 在训练集上训练网络\n",
    "- 在测试集上测试网络"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 加载数据\n",
    "使用`torchvision`很放方便的加载CIFAR10"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true,
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "import torch\n",
    "import torchvision\n",
    "import torchvision.transforms as transforms"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`torchvision`数据集输出的是PILImage格式的图片，像素范围在[0,1].我们将其转为Tensor，值为[-1,1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Files already downloaded and verified\n",
      "Files already downloaded and verified\n"
     ]
    }
   ],
   "source": [
    "transform = transforms.Compose(\n",
    "    [transforms.ToTensor(),\n",
    "     transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])\n",
    "\n",
    "trainset = torchvision.datasets.CIFAR10(root='./data', train=True,\n",
    "                                        download=True, transform=transform)\n",
    "trainloader = torch.utils.data.DataLoader(trainset, batch_size=4,\n",
    "                                          shuffle=True, num_workers=2)\n",
    "\n",
    "testset = torchvision.datasets.CIFAR10(root='./data', train=False,\n",
    "                                       download=True, transform=transform)\n",
    "testloader = torch.utils.data.DataLoader(testset, batch_size=4,\n",
    "                                         shuffle=False, num_workers=2)\n",
    "\n",
    "classes = ('plane', 'car', 'bird', 'cat',\n",
    "           'deer', 'dog', 'frog', 'horse', 'ship', 'truck')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "找几张图片看看"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\nr52IcMvZIl49AAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x20b5565b668>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " frog  frog  ship  bird\n"
     ]
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "\n",
    "# functions to show an image\n",
    "def imshow(img):\n",
    "    img = img / 2 + 0.5     # unnormalize\n",
    "    npimg = img.numpy()\n",
    "    plt.imshow(np.transpose(npimg, (1, 2, 0))) # 转换通道 C,H,W --> H,W,C\n",
    "    plt.show() # 注意原文档没有show，无法显示图片\n",
    "\n",
    "# 使用一个迭代器获取一些图片\n",
    "dataiter = iter(trainloader)\n",
    "images, labels = dataiter.next()\n",
    "\n",
    "# show images\n",
    "imshow(torchvision.utils.make_grid(images)) # 使用make_grid将几张图片合并到一个网格图片中\n",
    "# print labels\n",
    "print(' '.join('%5s' % classes[labels[j]] for j in range(4)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 定义卷积神经网络\n",
    "使用上一节用过的LeNet，将通道1改成3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Net(\n",
      "  (conv1): Conv2d(3, 6, kernel_size=(5, 5), stride=(1, 1))\n",
      "  (pool): MaxPool2d(kernel_size=(2, 2), stride=(2, 2), dilation=(1, 1), ceil_mode=False)\n",
      "  (conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))\n",
      "  (fc1): Linear(in_features=400, out_features=120, bias=True)\n",
      "  (fc2): Linear(in_features=120, out_features=84, bias=True)\n",
      "  (fc3): Linear(in_features=84, out_features=10, bias=True)\n",
      ")\n"
     ]
    }
   ],
   "source": [
    "from torch.autograd import Variable\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "\n",
    "\n",
    "class Net(nn.Module):\n",
    "    def __init__(self):\n",
    "        super(Net, self).__init__()\n",
    "        self.conv1 = nn.Conv2d(3, 6, 5) # 修改通道\n",
    "        self.pool = nn.MaxPool2d(2, 2)\n",
    "        self.conv2 = nn.Conv2d(6, 16, 5)\n",
    "        self.fc1 = nn.Linear(16 * 5 * 5, 120)\n",
    "        self.fc2 = nn.Linear(120, 84)\n",
    "        self.fc3 = nn.Linear(84, 10)\n",
    "\n",
    "    def forward(self, x):\n",
    "        x = self.pool(F.relu(self.conv1(x)))\n",
    "        x = self.pool(F.relu(self.conv2(x)))\n",
    "        x = x.view(-1, 16 * 5 * 5)\n",
    "        x = F.relu(self.fc1(x))\n",
    "        x = F.relu(self.fc2(x))\n",
    "        x = self.fc3(x)\n",
    "        return x\n",
    "\n",
    "\n",
    "net = Net()\n",
    "print(net)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 定义Loss\n",
    "使用交叉熵和带动量的SGD"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import torch.optim as optim\n",
    "\n",
    "criterion = nn.CrossEntropyLoss()\n",
    "optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 训练网络"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1,  2000] loss: 2.239\n",
      "[1,  4000] loss: 1.872\n",
      "[1,  6000] loss: 1.689\n",
      "[1,  8000] loss: 1.587\n",
      "[1, 10000] loss: 1.536\n",
      "[1, 12000] loss: 1.473\n",
      "[2,  2000] loss: 1.391\n",
      "[2,  4000] loss: 1.373\n",
      "[2,  6000] loss: 1.336\n",
      "[2,  8000] loss: 1.305\n",
      "[2, 10000] loss: 1.305\n",
      "[2, 12000] loss: 1.264\n",
      "Finished Training\n"
     ]
    }
   ],
   "source": [
    "for epoch in range(2):  # loop over the dataset multiple times\n",
    "\n",
    "    running_loss = 0.0\n",
    "    for i, data in enumerate(trainloader, 0):\n",
    "        # get the inputs\n",
    "        inputs, labels = data\n",
    "\n",
    "        # wrap them in Variable\n",
    "        inputs, labels = Variable(inputs), Variable(labels)\n",
    "\n",
    "        # zero the parameter gradients\n",
    "        optimizer.zero_grad() # 清空梯度\n",
    "\n",
    "        # forward + backward + optimize\n",
    "        outputs = net(inputs) #传入数据获得预测值\n",
    "        loss = criterion(outputs, labels) # 计算loss\n",
    "        loss.backward()   # 反向传播\n",
    "        optimizer.step() # 更新参数\n",
    "\n",
    "        # print statistics\n",
    "        running_loss += loss.data[0]\n",
    "        if i % 2000 == 1999:    # 每2000个mini-batches查看一下loss\n",
    "            print('[%d, %5d] loss: %.3f' %\n",
    "                  (epoch + 1, i + 1, running_loss / 2000))\n",
    "            running_loss = 0.0\n",
    "\n",
    "print('Finished Training')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 在测试集上测试模型\n",
    "上面已经在训练集上训练了2个epoch,下面看看模型在测试集上表现。同样的，先看看测试集图片。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n+P/jyitvLuJHGwAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x20b55616e10>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "GroundTruth:    cat  ship  ship plane\n"
     ]
    }
   ],
   "source": [
    "dataiter = iter(testloader)\n",
    "images, labels = dataiter.next()\n",
    "\n",
    "# print images\n",
    "imshow(torchvision.utils.make_grid(images))\n",
    "print('GroundTruth: ', ' '.join('%5s' % classes[labels[j]] for j in range(4)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([4, 10])\n"
     ]
    }
   ],
   "source": [
    "outputs = net(Variable(images))\n",
    "print(outputs.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "模型的输出是4个输出关于10个类别的概率值，我们找出概率最大的~"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Predicted:   ship   car  ship  ship\n"
     ]
    }
   ],
   "source": [
    "_, predicted = torch.max(outputs.data, 1)\n",
    "\n",
    "print('Predicted: ', ' '.join('%5s' % classes[predicted[j]]\n",
    "                              for j in range(4)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "结果错了一个，还算可以吧。可以看看模型在整个测试集上的表现："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy of the network on the 10000 test images: 54 %\n"
     ]
    }
   ],
   "source": [
    "correct = 0\n",
    "total = 0\n",
    "for data in testloader: # 迭代整个测试集\n",
    "    images, labels = data\n",
    "    outputs = net(Variable(images))\n",
    "    _, predicted = torch.max(outputs.data, 1)\n",
    "    total += labels.size(0)\n",
    "    correct += (predicted == labels).sum()\n",
    "\n",
    "print('Accuracy of the network on the 10000 test images: %d %%' % (\n",
    "    100 * correct / total))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "测试各个类别的表现："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy of plane : 57 %\n",
      "Accuracy of   car : 75 %\n",
      "Accuracy of  bird : 51 %\n",
      "Accuracy of   cat : 13 %\n",
      "Accuracy of  deer : 53 %\n",
      "Accuracy of   dog : 33 %\n",
      "Accuracy of  frog : 82 %\n",
      "Accuracy of horse : 68 %\n",
      "Accuracy of  ship : 69 %\n",
      "Accuracy of truck : 45 %\n"
     ]
    }
   ],
   "source": [
    "class_correct = list(0. for i in range(10))\n",
    "class_total = list(0. for i in range(10))\n",
    "for data in testloader:\n",
    "    images, labels = data\n",
    "    outputs = net(Variable(images))\n",
    "    _, predicted = torch.max(outputs.data, 1)\n",
    "    c = (predicted == labels).squeeze() \n",
    "    \n",
    "    for i in range(4): # 每个batch是4\n",
    "        label = labels[i]\n",
    "        class_correct[label] += c[i] # 统计每个种类预测对的\n",
    "        class_total[label] += 1  # 终极每个种类一共有多少个\n",
    "\n",
    "for i in range(10):\n",
    "    print('Accuracy of %5s : %2d %%' % (\n",
    "        classes[i], 100 * class_correct[i] / class_total[i]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
